package com.mock.dao.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.mock.dao.TeamDao;
import com.mock.model.DataTable;
import com.mock.model.Team;
import com.mock.utils.HibernateUtil;

public class TeamDaoImpl extends GenericDaoImpl<Team, Long> implements TeamDao {
	
	@Override
	public List<Team> getAllTeam() {
		return super.getAll(Team.class);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Team> getTeamByQuery(DataTable datatable, long departmentId) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		Criteria criteria = session.createCriteria(Team.class, "team");
		criteria.createAlias("team.contact", "contact");
		criteria.setFetchMode("team.contact", FetchMode.JOIN);
		criteria.createAlias("team.department", "department");
		criteria.setFetchMode("team.department", FetchMode.JOIN);
		
		//Get Team By DepartmentId
		criteria.add(Restrictions.like("department.id", departmentId));
		
		// Filter by Letter
		Disjunction disjunction = Restrictions.disjunction();
		if ("^[0-9]".equalsIgnoreCase(datatable.sSearch_0)) {
			for (int i = 0; i < 10; i++) {
				disjunction.add(Restrictions.ilike("team.name", i + "%"));
			}
			criteria.add(disjunction);
		} else {
			criteria.add(Restrictions.ilike("team.name", datatable.sSearch_0.replace("^", "") + "%"));
		}
		
		// Get Sort Column Name
		String columnName = "name";
		switch (datatable.iSortCol_0) {
		case 0:
			columnName = "name";
			break;
		case 1:
			columnName = "addressLine1";
			break;
		case 2:
			columnName = "postcode";
			break;
		case 3:
			if ("asc".equalsIgnoreCase(datatable.sSortDir_0)) {
				criteria.addOrder(Order.asc("contact.firstname"));
				criteria.addOrder(Order.asc("contact.surname"));
			} else {
				criteria.addOrder(Order.desc("contact.firstname"));
				criteria.addOrder(Order.desc("contact.surname"));
			}
			columnName = "contact.firstname";
			break;
		case 4:
			columnName = "active";
			break;
		default:
			break;
		}

		// Get Sort Direction
		if ("asc".equalsIgnoreCase(datatable.sSortDir_0) && datatable.iSortCol_0 != 3) {
			criteria.addOrder(Order.asc(columnName));
		} else {
			criteria.addOrder(Order.desc(columnName));
		}
		// Filter in-active
		if ("".equalsIgnoreCase(datatable.sSearch_4)) {

		} else if ("Yes".equalsIgnoreCase(datatable.sSearch_4)) {
			criteria.add(Restrictions.eq("active", true));
		}

		// Paging
		criteria.setFirstResult(datatable.iDisplayStart);
		criteria.setMaxResults(datatable.iDisplayLength);
		
		List<Team> teams = criteria.list();
		
		session.getTransaction().commit();
		return teams;
	}

	@Override
	public int getRowCount() {
		
		return super.getRowCount(Team.class);
	}
	
	@Override
	public List<Team> getTeamByDepartmentId(long departmentId) {
		return super.getListByColumn(Team.class, "departmentId", Long.toString(departmentId));
	}

	@SuppressWarnings("unchecked")
	@Override
	public Long getTotalRecordByQuery(DataTable datatable, long departmentId) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		Criteria criteria = session.createCriteria(Team.class, "team");
		criteria.createAlias("team.contact", "contact");
		criteria.setFetchMode("team.contact", FetchMode.JOIN);
		criteria.createAlias("team.department", "department");
		criteria.setFetchMode("team.department", FetchMode.JOIN);
		
		//Get Team By DepartmentId
		criteria.add(Restrictions.like("department.id", departmentId));
		
		// Filter by Letter
		Disjunction disjunction = Restrictions.disjunction();
		if ("^[0-9]".equalsIgnoreCase(datatable.sSearch_0)) {
			for (int i = 0; i < 10; i++) {
				disjunction.add(Restrictions.ilike("team.name", i + "%"));
			}
			criteria.add(disjunction);
		} else {
			criteria.add(Restrictions.ilike("team.name", datatable.sSearch_0.replace("^", "") + "%"));
		}
		
		// Filter in-active
		if ("".equalsIgnoreCase(datatable.sSearch_4)) {

		} else if ("Yes".equalsIgnoreCase(datatable.sSearch_4)) {
			criteria.add(Restrictions.eq("active", true));
		}
		
		Long sizes = (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();		
		session.getTransaction().commit();
		return sizes;
	}
	
}
